<Project InitialTargets="ValidateTargetOSLowercase">
  <PropertyGroup>
    <!--
    For non-SDK projects that import this file and then import Microsoft.Common.targets,
    tell Microsoft.Common.targets not to import Directory.Build.targets again
    -->
    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>
  </PropertyGroup>

  <Import Project="$(RepositoryEngineeringDir)Analyzers.targets" />
  <Import Project="Sdk.targets" Sdk="Microsoft.DotNet.Arcade.Sdk" />
  <Import Project="$(RepositoryEngineeringDir)liveBuilds.targets" />
  <Import Project="$(RepositoryEngineeringDir)generators.targets" />
  <Import Project="$(RepositoryEngineeringDir)python.targets" />
  <Import Project="$(RepositoryEngineeringDir)generatorProjects.targets" Condition="'$(IsGeneratorProject)' == 'true'" />
  <Import Project="$(RepositoryEngineeringDir)resolveContract.targets" Condition="'$(IsSourceProject)' == 'true'" />
  <Import Project="$(RepositoryEngineeringDir)packaging.targets" Condition="'$(IsPackable)' == 'true' and '$(MSBuildProjectExtension)' != '.pkgproj'" />
  <Import Project="$(RepositoryEngineeringDir)slngen.targets" Condition="'$(IsSlnGen)' == 'true'" />

  <!--
  When .NET gets built from source, make the SDK aware there are bootstrap packages
  for Microsoft.NETCore.App.Runtime.<rid> and Microsoft.NETCore.App.Crossgen2.<rid>.
  -->
  <ItemGroup Condition="'$(DotNetBuildSourceOnly)' == 'true'">
    <KnownFrameworkReference Update="Microsoft.NETCore.App">
      <RuntimePackRuntimeIdentifiers
        Condition="'%(TargetFramework)' == '$(NetCoreAppCurrent)'">%(RuntimePackRuntimeIdentifiers);$(PackageRID)</RuntimePackRuntimeIdentifiers>
    </KnownFrameworkReference>
    <KnownCrossgen2Pack Update="Microsoft.NETCore.App.Crossgen2">
      <Crossgen2RuntimeIdentifiers
        Condition="'%(TargetFramework)' == '$(NetCoreAppCurrent)'" >%(Crossgen2RuntimeIdentifiers);$(PackageRID)</Crossgen2RuntimeIdentifiers>
    </KnownCrossgen2Pack>
    <!-- Avoid references to Microsoft.AspNetCore.App.Runtime.<rid> -->
    <KnownFrameworkReference Remove="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <PropertyGroup>
    <!--
      Define this here (not just in Versions.props) because the SDK resets it
      unconditionally in Microsoft.NETCoreSdk.BundledVersions.props.
    -->
    <NETCoreAppMaximumVersion>$(MajorVersion).$(MinorVersion)</NETCoreAppMaximumVersion>
    <!-- SDK sets product to assembly but we want it to be our product name -->
    <Product>Microsoft%AE .NET</Product>
    <!-- Use the .NET product branding version for informational version description -->
    <InformationalVersion Condition="'$(InformationalVersion)' == '' and '$(VersionSuffix)' == ''">$(ProductVersion)</InformationalVersion>
    <InformationalVersion Condition="'$(InformationalVersion)' == '' and '$(PreReleaseVersionLabel)' == 'servicing'">$(ProductVersion)</InformationalVersion>
    <InformationalVersion Condition="'$(InformationalVersion)' == '' and '$(VersionSuffix)' != ''">$(ProductVersion)-$(VersionSuffix)</InformationalVersion>
  </PropertyGroup>

  <ItemGroup>
    <SupportedNETCoreAppTargetFramework Include=".NETCoreApp,Version=v$(NETCoreAppMaximumVersion)" DisplayName=".NET $(NETCoreAppMaximumVersion)" Alias="net$(NETCoreAppMaximumVersion)" />
  </ItemGroup>

  <!-- The Default behavior in VS is to show files for the first target framework in TargetFrameworks property.
       This is required to show all the files corresponding to all target frameworks in VS. -->
  <ItemGroup Condition="'$(DefaultLanguageSourceExtension)' != '' and
                        ('$(BuildingInsideVisualStudio)' == 'true' or '$(DesignTimeBuild)' == 'true')">
    <None Include="$(MSBuildProjectDirectory)\**\*$(DefaultLanguageSourceExtension)"
          Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);@(Compile)" />
  </ItemGroup>

  <!-- Packaging -->
  <ItemGroup Condition="'$(IsPackable)' == 'true'">
    <!-- The sfxproj files add the license themselves. -->
    <None Include="$(LicenseFile)"
          PackagePath="$([System.IO.Path]::GetFileName('$(LicenseFile)'))"
          Pack="true"
          Condition="'$(MSBuildProjectExtension)' != '.sfxproj' and '$(MSBuildProjectFile)' != 'msi.csproj'" />
    <None Include="$(PackageThirdPartyNoticesFile)"
          PackagePath="$([System.IO.Path]::GetFileName('$(PackageThirdPartyNoticesFile)'))"
          Pack="true" />
  </ItemGroup>

  <PropertyGroup>
    <PackageDescription Condition="'$(PackageDescription)' == '' and '$(Description)' != ''">$(Description)</PackageDescription>
    <RuntimePackageDisclaimer>Internal implementation package not meant for direct consumption. Please do not reference directly.</RuntimePackageDisclaimer>
    <UseRuntimePackageDisclaimer Condition="'$(UseRuntimePackageDisclaimer)' == '' and
                                            ($(MSBuildProjectName.StartsWith('runtime.native')) or '$(PackageTargetRuntime)' != '')">true</UseRuntimePackageDisclaimer>
    <PackageDescription Condition="'$(PackageDescription)' != '' and '$(UseRuntimePackageDisclaimer)' == 'true'">$(RuntimePackageDisclaimer) %0A$(PackageDescription)</PackageDescription>
    <PackageDescription Condition="'$(PackageDescription)' == '' and '$(UseRuntimePackageDisclaimer)' == 'true'">$(RuntimePackageDisclaimer)</PackageDescription>
    <!-- Keep in sync as required by the Packaging SDK in Arcade. -->
    <Description>$(PackageDescription)</Description>
    <!-- Until we update the TFM to match the Major version, we need to patch in support for RequiresPreviewFeatures -->
    <GenerateRequiresPreviewFeaturesAttribute Condition="'$(TargetFrameworkMoniker)' == '$(NetCoreAppCurrentTargetFrameworkMoniker)'">true</GenerateRequiresPreviewFeaturesAttribute>
  </PropertyGroup>

  <PropertyGroup>
    <!-- when building from source we need to use the current version of MetadataLoadContext as the toolset version, but source-build imports
         another props file which overrides the SystemReflectionMetadataLoadContextVersion from Version.props so we can't set it there -->
    <SystemReflectionMetadataLoadContextToolsetVersion Condition="'$(DotNetBuildSourceOnly)' == 'true'">$(SystemReflectionMetadataLoadContextVersion)</SystemReflectionMetadataLoadContextToolsetVersion>
  </PropertyGroup>

  <Target Name="ValidateTargetOSLowercase"
          Condition="!$(TargetOS.Equals($(TargetOS.ToLower()), StringComparison.InvariantCulture))">
    <Error Text="The passed-in TargetOS property value '$(TargetOS)' must be lowercase." />
  </Target>

  <ItemDefinitionGroup>
    <TargetPathWithTargetPlatformMoniker>
      <IsReferenceAssemblyProject>$(IsReferenceAssemblyProject)</IsReferenceAssemblyProject>
    </TargetPathWithTargetPlatformMoniker>
  </ItemDefinitionGroup>

  <Target Name="ValidateReferenceAssemblyProjectReferencesAndTargetFramework"
          AfterTargets="ResolveReferences"
          Condition="'$(IsReferenceAssemblyProject)' == 'true' and
                     '$(SkipValidateReferenceAssemblyProjectReferences)' != 'true'">
    <Error Text="Reference assemblies must only reference other reference assemblies and '%(ReferencePath.ProjectReferenceOriginalItemSpec)' is not a reference assembly project and does not set 'ProduceReferenceAssembly'."
           Condition="'%(ReferencePath.ReferenceSourceTarget)' == 'ProjectReference' and '%(ReferencePath.IsReferenceAssemblyProject)' != 'true' and '%(ReferencePath.ReferenceAssembly)' == ''" />
    <Error Text="Reference assemblies must be TargetPlatform agnostic. $(MSBuildProjectName) incorrectly targets $(TargetFramework), platform: $(TargetPlatformIdentifier)."
           Condition="'$(TargetPlatformIdentifier)' != ''" />
  </Target>

  <!-- For experimental ref assemblies (which typically have the same name as a regular ref
       assembly), bump their minor file version by 100 to make it distinguishable from the regular
       ref assembly. -->
  <Target Name="UpdateExperimentalRefAssemblyFileVersion"
          AfterTargets="_InitializeAssemblyVersion"
	        Condition="'$(IsReferenceAssemblyProject)' == 'true' and '$(IsExperimentalRefAssembly)' == 'true'">
    <PropertyGroup>
      <_FileVersionMaj>$(FileVersion.Split('.')[0])</_FileVersionMaj>
      <_FileVersionMin>$(FileVersion.Split('.')[1])</_FileVersionMin>
      <_FileVersionBld>$(FileVersion.Split('.')[2])</_FileVersionBld>
      <_FileVersionRev>$(FileVersion.Split('.')[3])</_FileVersionRev>
      <FileVersion>$(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev)</FileVersion>
    </PropertyGroup>
  </Target>

  <!-- Allows building against source assemblies when the 'SkipUseReferenceAssembly' attribute is present on ProjectReference items. -->
  <Target Name="HandleReferenceAssemblyAttributeForProjectReferences"
          AfterTargets="ResolveProjectReferences"
          BeforeTargets="FindReferenceAssembliesForReferences"
          Condition="'@(ProjectReference)' != '' and '@(_ResolvedProjectReferencePaths)' != ''">
    <!-- If we have a ProjectReference to CoreLib, we need to compile against implementation assemblies,
         and ignore architecture mismatches in those implementation assemblies. -->
    <PropertyGroup Condition="@(_ResolvedProjectReferencePaths->AnyHaveMetadataValue('MSBuildSourceProjectFile', '$(CoreLibProject)'))">
      <CompileUsingReferenceAssemblies Condition="'$(CompileUsingReferenceAssemblies)' == ''">false</CompileUsingReferenceAssemblies>
      <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>

    <!-- Clear the ReferenceAssembly attribute on resolved P2Ps that set SkipUseReferenceAssembly to true. -->
    <ItemGroup>
      <_ResolvedProjectReferencePaths Condition="'%(_ResolvedProjectReferencePaths.SkipUseReferenceAssembly)' == 'true'"
                                      ReferenceAssembly="" />
    </ItemGroup>
  </Target>

  <!-- Filter out transitive P2Ps which should be excluded. -->
  <Target Name="FilterTransitiveProjectReferences"
          AfterTargets="IncludeTransitiveProjectReferences"
          Condition="'$(DisableTransitiveProjectReferences)' != 'true' and
                     '@(DefaultReferenceExclusion)' != ''">
    <ItemGroup>
      <_transitiveProjectReferenceWithProjectName Include="@(ProjectReference->Metadata('NuGetPackageId'))"
                                                  OriginalIdentity="%(Identity)" />
      <_transitiveIncludedProjectReferenceWithProjectName Include="@(_transitiveProjectReferenceWithProjectName)"
                                                          Exclude="@(DefaultReferenceExclusion)" />
      <_transitiveExcludedProjectReferenceWithProjectName Include="@(_transitiveProjectReferenceWithProjectName)"
                                                          Exclude="@(_transitiveIncludedProjectReferenceWithProjectName)" />
      <ProjectReference Remove="@(_transitiveExcludedProjectReferenceWithProjectName->Metadata('OriginalIdentity'))" />
    </ItemGroup>
  </Target>

  <!-- Filter out conflicting implicit assembly references. -->
  <Target Name="FilterImplicitAssemblyReferences"
          Condition="'$(DisableImplicitFrameworkReferences)' != 'true'"
          DependsOnTargets="ResolveProjectReferences"
          AfterTargets="ResolveTargetingPackAssets">
    <ItemGroup>
      <_targetingPackReferenceExclusion Include="$(TargetName)" />
      <_targetingPackReferenceExclusion Include="@(_ResolvedProjectReferencePaths->Metadata('Filename'))" />
      <_targetingPackReferenceExclusion Include="@(DefaultReferenceExclusion)" />
    </ItemGroup>

    <!-- Filter out shims from the targeting pack references as an opt-in. -->
    <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and
                          '$(SkipTargetingPackShimReferences)' == 'true'">
      <_targetingPackReferenceExclusion Include="@(NetFxReference)" />
      <_targetingPackReferenceExclusion Include="netstandard" />
    </ItemGroup>

    <ItemGroup>
      <_targetingPackReferenceWithProjectName Include="@(Reference->WithMetadataValue('ExternallyResolved', 'true')->Metadata('Filename'))"
                                              OriginalIdentity="%(Identity)" />
      <_targetingPackIncludedReferenceWithProjectName Include="@(_targetingPackReferenceWithProjectName)"
                                                      Exclude="@(_targetingPackReferenceExclusion)" />
      <_targetingPackExcludedReferenceWithProjectName Include="@(_targetingPackReferenceWithProjectName)"
                                                      Exclude="@(_targetingPackIncludedReferenceWithProjectName)" />
      <Reference Remove="@(_targetingPackExcludedReferenceWithProjectName->Metadata('OriginalIdentity'))" />
    </ItemGroup>

    <ItemGroup>
      <_targetingPackAnalyzerReferenceWithProjectName Include="@(Analyzer->WithMetadataValue('ExternallyResolved', 'true')->Metadata('Filename'))"
                                                      OriginalIdentity="%(Identity)" />
      <_targetingPackIncludedAnalyzerReferenceWithProjectName Include="@(_targetingPackAnalyzerReferenceWithProjectName)"
                                                              Exclude="@(_targetingPackReferenceExclusion)" />
      <_targetingPackExcludedAnalyzerReferenceWithProjectName Include="@(_targetingPackAnalyzerReferenceWithProjectName)"
                                                              Exclude="@(_targetingPackIncludedAnalyzerReferenceWithProjectName)" />
      <Analyzer Remove="@(_targetingPackExcludedAnalyzerReferenceWithProjectName->Metadata('OriginalIdentity'))" />
    </ItemGroup>
  </Target>

  <!--
    Arcade SDK versioning is defined by static properties in a targets file: work around this by
    moving properties based on versioning into a target.
  -->
  <Target Name="GetProductVersions">
    <PropertyGroup>
      <IncludePreReleaseLabelInPackageVersion Condition="'$(DotNetFinalVersionKind)' != 'release'">true</IncludePreReleaseLabelInPackageVersion>
      <IncludePreReleaseLabelInPackageVersion Condition="'$(SuppressFinalPackageVersion)' == 'true'">true</IncludePreReleaseLabelInPackageVersion>
      <IncludePreReleaseLabelInPackageVersion Condition="'$(IsShipping)' != 'true'">true</IncludePreReleaseLabelInPackageVersion>

      <IncludeBuildNumberInPackageVersion Condition="'$(StabilizePackageVersion)' != 'true'">true</IncludeBuildNumberInPackageVersion>
      <IncludeBuildNumberInPackageVersion Condition="'$(SuppressFinalPackageVersion)' == 'true'">true</IncludeBuildNumberInPackageVersion>
      <IncludeBuildNumberInPackageVersion Condition="'$(IsShipping)' != 'true'">true</IncludeBuildNumberInPackageVersion>

      <ProductVersionSuffix Condition="'$(IncludePreReleaseLabelInPackageVersion)' == 'true'">-$(VersionSuffix)</ProductVersionSuffix>
      <ProductBandVersion Condition="'$(ProductBandVersion)' == ''">$(MajorVersion).$(MinorVersion)</ProductBandVersion>
      <ProductionVersion Condition="'$(ProductionVersion)' == ''">$(ProductBandVersion).$(PatchVersion)</ProductionVersion>
      <ProductVersion>$(ProductionVersion)$(ProductVersionSuffix)</ProductVersion>

      <SharedFrameworkNugetVersion>$(ProductVersion)</SharedFrameworkNugetVersion>
      <NuGetVersion>$(SharedFrameworkNugetVersion)</NuGetVersion>
      <InstallersRelativePath>Runtime/$(SharedFrameworkNugetVersion)/</InstallersRelativePath>
    </PropertyGroup>
  </Target>

</Project>
